package com.hermes.comics.data;

import java.util.ArrayList;
import java.util.List;
import java.util.Map;
import java.util.Set;
import java.util.TreeMap;
import java.util.TreeSet;

public class Serie extends Item<SerieTag> implements Comparable<Serie> {

  private final Map<String, Issue> issuesMap;
  private final Catalog catalog;

  public Serie() {
    super("SERIE");
    this.issuesMap = new TreeMap<String, Issue>();
    this.catalog = Catalog.getInstance();
  }

  public Set<Issue> missing() {
    Set<Issue> missing = new TreeSet<Issue>();
    for (Issue issue : issues()) {
      if ("Y".equals(issue.getTagValue(IssueTag.MISSING))) {
        missing.add(issue);
      }
    }
    return missing;
  }

  public Set<Issue> read() {
    Set<Issue> issues = new TreeSet<Issue>();
    for (Issue issue : issues()) {
      if (!"N".equals(issue.getTagValue(IssueTag.READ))) {
        issues.add(issue);
      }
    }
    return issues;
  }

  public List<Issue> issues() {
    return new ArrayList<Issue>(issuesMap.values());
  }

  public Issue getIssue(String number) {
    for (Issue issue : issues()) {
      if (number.equals(issue.getTagValue(IssueTag.KEY))) {
        return issue;
      }
    }
    return null;
  }

  public Serie removeIssue(Issue issue) {
    issuesMap.remove(issue.paddedKey());
    return this;
  }

  public Serie addIssue(Issue issue) {
    removeIssue(issue);
    issuesMap.put(issue.paddedKey(), issue);
    return this;
  }

  @Override
  public List<String> row() {
    Map<String, String> fields = new TreeMap<String, String>();
    for (SerieTag tag : SerieTag.values()) {
      String value = tag.isBoolValue() ? getTagValue(tag, "N") : getTagValue(tag, "");
      fields.put(String.format("%4d", tag.index()), value.replace("#", " "));
    }
    return new ArrayList<String>(fields.values());
  }

  @Override
  public int compareTo(Serie s) {
    return this.toString().compareTo(s.toString());
  }

  @Override
  public String toString() {
    return getTagValue(SerieTag.TITLE);
  }

  public String serialize() {
    StringBuilder builder = new StringBuilder();
    for (SerieTag tag : SerieTag.values()) {
      builder.append(tag.toString());
      builder.append("#");
      builder.append(getTagValue(tag, ""));
      builder.append("\t");
    }
    return builder.toString().trim();
  }

  public static Serie unserialize(String input) {
    Serie serie = new Serie();
    for (String fields : input.split("\t")) {
      String[] tagpair = fields.split("#");
      String value = "";
      for (int i = 1; i < tagpair.length; ++i) {
        value += tagpair[i] + " ";
      }
      serie.setTag(SerieTag.getTagByString(tagpair[0]), value.trim());
    }
    return serie;
  }

  public String verbose() {
    StringBuffer buffer = new StringBuffer();
    buffer.append("{\n");
    buffer.append(verbose("  "));

    for (Issue issue : issues()) {
      buffer.append(issue.verbose());
    }

    buffer.append("}\n");

    return buffer.toString();
  }

  @Override
  public boolean equals(Object obj) {
    if (obj instanceof Serie) {
      Serie other = (Serie) obj;

      return this.getTagValue(SerieTag.KEY).equals(other.getTagValue(SerieTag.KEY));
    }

    return false;
  }
}
